package com.huixi.microspur.web.util;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;


/**
 * 阿里巴巴OSS存储库,对上传下载删除修改的一个封装
 * 注意：用的时候必须使用@AutoWrite ，不然不会生效
 *
 * @author: 李辉
 * @date: 2019/9/8 1:01
 * @param:
 * @return:
 */
@Configuration
@Slf4j
public class AlibabaOSS {


    /**
      * 外网访问
      *@author: 李辉
      *@date: 2019/10/27 17:02
      */
    @Value("${alibabaOSS.endpoint}")
    private String endpoint;

    /**
      * 内网访问
      *@author: 李辉
      *@date: 2019/10/27 17:03
      */
    @Value("${alibabaOSS.endpointIntranet}")
    private String endpointIntranet;

    @Value("${alibabaOSS.accessKeyId}")
    private String accessKeyId;

    @Value("${alibabaOSS.accessKeySecret}")
    private String accessKeySecret;

    @Value("${alibabaOSS.bucketName}")
    private String bucketName;

    /**
      * 操作外网
      *@author: 李辉
      *@date: 2019/10/27 16:34
      *@param:
      *@return:
      */
    public OSS getOssClient() {

        // 创建OSSClient实例。官方封装了对操作文件的方法
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        return ossClient;

    }

    /**
      * 操作内网
      *@author: 李辉
      *@date: 2019/10/27 16:34
      *@param:
      *@return:
      */
    public OSS getOssIntranetClient() {

        // 创建OSSClient实例。官方封装了对操作文件的方法
        OSS ossClient = new OSSClientBuilder().build(endpointIntranet, accessKeyId, accessKeySecret);
        return ossClient;

    }

    /**
     *
     * @Title: uploadByNetworkStream
     * @Description: 通过网络流上传文件
     * @param url 			URL
     * @param bucketName 	bucket名称
     * @param objectName 	上传文件目录和（包括文件名）例如“test/index.html”
     * @return void 		返回类型
     * @throws
     */
    public void uploadByNetworkStream(OSS ossClient, URL url, String bucketName, String objectName) {
        try {
            InputStream inputStream = url.openStream();
            ossClient.putObject(bucketName, objectName, inputStream);
            ossClient.shutdown();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     *
     * @Title: uploadByInputStream
     * @Description: 通过输入流上传文件
     * @param inputStream 	输入流
     * @param bucketName 	bucket名称
     * @param objectName 	上传文件目录和（包括文件名） 例如“test/a.jpg”
     * @return void 		返回类型
     * @throws
     */
    public void uploadByInputStream(OSS ossClient, InputStream inputStream, String bucketName, String objectName) {
        try {
            ossClient.putObject(bucketName, objectName, inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     *
     * @Title: uploadByFile
     * @Description: 通过file上传文件
     * @param file 			上传的文件
     * @param objectName 	上传文件目录和（包括文件名） 例如“test/a.jpg”
     * @return void 		返回类型
     * @throws
     */
    public void uploadByFile(OSS ossClient, File file, String objectName) {
        try {
            ossClient.putObject(bucketName, objectName, file);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }


    /**
     *
     * @Title: deleteFile
     * @Description: 根据key删除oss服务器上的文件
     * @param bucketName		bucket名称
     * @param key    		文件路径/名称，例如“test/a.txt”
     * @return void    		返回类型
     * @throws
     */
    public void deleteFile(OSS ossClient, String bucketName, String key) {
        ossClient.deleteObject(bucketName, key);
    }

    /**
     *
     * @Title: getInputStreamByOSS
     * @Description:根据key获取服务器上的文件的输入流
     * @param bucketName 	bucket名称
     * @param key 			文件路径和名称
     * @return InputStream 	文件输入流
     * @throws
     */
    public InputStream getInputStreamByOSS(OSS ossClient ,String bucketName, String key) throws IOException {
        InputStream content = null;
        try {
            OSSObject ossObj = ossClient.getObject(bucketName, key);
            content = ossObj.getObjectContent();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            content.close();
        }
        return content;
    }

    /**
     *
     * @Title: queryAllObject
     * @Description: 查询某个bucket里面的所有文件
     * @param bucketName		bucket名称
     * @return List<String>  文件路径和大小集合
     * @throws
     */
    public List<String> queryAllObject(OSS ossClient, String bucketName) {
        List<String> results = new ArrayList<String>();
        try {
            // ossClient.listObjects返回ObjectListing实例，包含此次listObject请求的返回结果。
            ObjectListing objectListing = ossClient.listObjects(bucketName);
            // objectListing.getObjectSummaries获取所有文件的描述信息。
            for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
                results.add(" - " + objectSummary.getKey() + "  " + "(size = " + objectSummary.getSize() + ")");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return results;
    }


    public String getEndpoint() {
        return endpoint;
    }

    public void setEndpoint(String endpoint) {
        this.endpoint = endpoint;
    }

    public String getEndpointIntranet() {
        return endpointIntranet;
    }

    public void setEndpointIntranet(String endpointIntranet) {
        this.endpointIntranet = endpointIntranet;
    }

    public String getAccessKeyId() {
        return accessKeyId;
    }

    public void setAccessKeyId(String accessKeyId) {
        this.accessKeyId = accessKeyId;
    }

    public String getAccessKeySecret() {
        return accessKeySecret;
    }

    public void setAccessKeySecret(String accessKeySecret) {
        this.accessKeySecret = accessKeySecret;
    }

    public String getBucketName() {
        return bucketName;
    }

    public void setBucketName(String bucketName) {
        this.bucketName = bucketName;
    }
}
